shadcn.io is not affiliated with official shadcn/ui
Components
Free
Floating Panel for Vue
A window you can drag, resize, and minimize while the page underneath stays usable. For Vue with Ark UI, when a modal would block the work under it.
Framework
UI library
A small window over the page. You can drag the header, resize from the edges, and minimize it without blocking the page.
Use it when a tool should stay beside the work. A task that has to finish before anything else is a Dialog. In Vue, Ark UI portals the window and remembers its position and size.
Installation
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
position is in state, and the arrow buttons nudge it by 20 on each axis. Dragging the header writes the same state, so the readout and the window agree. Control position when something outside moves the panel, or when you show the coordinates. Omit position when the panel should track a drag itself, and expect a blank readout until the first move.
Controlled Size
size starts at a width of 360 and a height of 200. Shrink and Grow change it, and dragging an edge writes back through the size callback. Control size when a button must set the rect, not only the pointer. defaultSize is enough when you only care about the opening box, and nothing here sets minSize or maxSize, so the buttons can push it quite small.
Custom Spacing
The --space variable on FloatingPanelContent is the padding shared by the header, the body, and the footer. This one tightens it on a narrow screen and loosens it from the small breakpoint up. Change the variable once, because padding each part yourself fights that layout. It does not move the window or change its size.
FAQ
How do I control a Floating Panel's position in Vue?
Keep the position in state and pass it back so a drag and your own buttons stay in sync. Omit it when the panel should track position itself, and use defaultPosition only for the starting point. Set persistRect to keep that rect after the panel closes.
@position-change receives details.position, with x and y, and you pass that object as position, or bind v-model:position.
How do I control the size of a Floating Panel?
Pass width and height on size when state should own the rect, and write the next size back from the resize callback. Use defaultSize when you only need a start, as in Usage, which starts at a width of 360 and a height of 300. minSize and maxSize clamp the drag.
@size-change receives details.size, with width and height, or bind v-model:size.
How do I open a Floating Panel from state in Vue?
Pass the boolean back as open when a parent should show or hide the panel. Leave open unset for an uncontrolled panel, and use defaultOpen for the first state only. Closed content unmounts, so set lazyMount and unmountOnExit to false when form fields must stay mounted.
Bind v-model:open, or listen to @open-change, which receives details.open.
How do I minimize or maximize a Floating Panel?
Use FloatingPanelMinimize, FloatingPanelMaximize, and FloatingPanelRestore in the header. They switch the stage among minimized, maximized, and default, and the restore icon follows the current stage. The content exposes data-minimized and data-maximized for styling. Dragging uses the header, which is the drag handle, unless you set draggable to false.
Does Escape close a Floating Panel?
No, Escape leaves a Floating Panel open unless you set closeOnEscape. The Accessibility section lists the keys that do apply: arrows move the panel, and Home and End jump. The panel is portaled and uses z-50, so overflow on a parent does not clip it. Set resizable to false on FloatingPanelContent to drop the edge handles.
How do I change the spacing inside a Floating Panel?
Padding comes from the --space variable on the content. Header, body, and footer all read it, so change --space on FloatingPanelContent once, as the Custom Spacing demo does, instead of padding each part. The positioner places the window with --x, --y, --width, and --height.
When should I use a Floating Panel instead of a Dialog?
Use a Floating Panel when the window should stay available while people drag, resize, or minimize it. Use a Dialog when the task should block the page until it is dismissed. Use a Popover for a small anchored surface, and a Sheet when a small screen needs an edge panel instead of a free window.
How do I install Floating Panel in Vue?
Run the command in the Installation section above. It adds Floating Panel to your ui folder, including the trigger, content, header, body, footer, and the stage and close controls. Install from that section rather than pasting a partial tree, so the parts and their dependencies stay together.
The command uses the shadcn-vue CLI.
API Reference
FloatingPanel
data-slot="floating-panel"
PropType
open?boolean
The controlled open state of the panel. Two-way with v-model:open.
defaultOpen?boolean
The initial open state of the panel when rendered.
Use when you don't need to control the open state of the panel.
Default
false
position?object
The controlled position of the panel. Two-way with v-model:position.
Type
{ x: number; y: number }
defaultPosition?object
The initial position of the panel when rendered.
Use when you don't need to control the position of the panel.
Type
{ x: number; y: number }
size?object
The size of the panel. Two-way with v-model:size.
Type
{ width: number; height: number }
defaultSize?object
The default size of the panel.
Type
{ width: number; height: number }
allowOverflow?boolean
Whether the panel should be strictly contained within the boundary when dragging. Ark default: true.
Default
!inPreview
closeOnEscape?boolean
Whether the panel should close when the escape key is pressed.
dir?"ltr" | "rtl"
The document's text/writing direction.
Type
"ltr" | "rtl"
Default
"ltr"
disabled?boolean
Whether the panel is disabled.
draggable?boolean
Whether the panel is draggable.
Default
true
finalFocusEl?() → HTMLElement | null
Element to receive focus when the panel is closed.
By default, the trigger element is focused.
Type
() → HTMLElement | null
Returns
HTMLElement | null
getAnchorPosition?(details: AnchorPositionDetails) → Point
Function that returns the initial position of the panel when it is opened.
If provided, will be used instead of the default position.
The boundary of the panel. Useful for recalculating the boundary rect when
the it is resized.
Type
() → HTMLElement | null
Returns
HTMLElement | null
gridSize?number
The snap grid for the panel.
Default
1
hideMode?"display-none" | "activity"
How to hide content when mounted but not present.
- display-none: HTML hidden attribute. Effects stay alive.
- activity: React 19 <Activity mode="hidden">. Effects pause. Requires React 19+.
Type
"display-none" | "activity"
Default
"display-none"
id?string
The unique identifier of the machine.
ids?object
The ids of the elements in the floating panel. Useful for composition.