This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing from the bottom-right corner.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, MinimizeIcon, XIcon, MinusIcon, MaximizeIcon } from 'lucide-react';
export default function Default() {
return (
<FloatingPanel>
<FloatingPanel.Trigger className="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>
This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing
from the bottom-right corner.
</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
);
}This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing from the bottom-right corner.
<script>
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<FloatingPanel>
<FloatingPanel.Trigger class="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>
This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing from
the bottom-right corner.
</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>Size Constraints
Use the minSize and maxSize props to set size constraints on the Floating Panel.
This panel has size constraints applied: minimum 300x200 pixels and maximum 900x600 pixels.
Try resizing from the bottom-right corner - the panel will respect these boundaries.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, MinimizeIcon, XIcon, MinusIcon, MaximizeIcon } from 'lucide-react';
export default function SizeConstraints() {
return (
<FloatingPanel maxSize={{ width: 900, height: 600 }} minSize={{ width: 300, height: 200 }}>
<FloatingPanel.Trigger className="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel has size constraints applied: minimum 300x200 pixels and maximum 900x600 pixels.</p>
<p>Try resizing from the bottom-right corner - the panel will respect these boundaries.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
);
}This panel has size constraints applied: minimum 300x200 pixels and maximum 900x600 pixels.
Try resizing from the bottom-right corner - the panel will respect these boundaries.
<script>
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<FloatingPanel maxSize={{ width: 900, height: 600 }} minSize={{ width: 300, height: 200 }}>
<FloatingPanel.Trigger class="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel has size constraints applied: minimum 300x200 pixels and maximum 900x600 pixels.</p>
<p>Try resizing from the bottom-right corner - the panel will respect these boundaries.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>Controlled
Control the open state and size of the Floating Panel with your own state.
This panel's open state and size are controlled via the inputs above.
Try changing the values or resizing/closing the panel to see the inputs update.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, XIcon, MinusIcon, MaximizeIcon, MinimizeIcon } from 'lucide-react';
import { useState } from 'react';
export default function Controlled() {
const [open, setOpen] = useState(false);
const [size, setSize] = useState({
width: 400,
height: 300,
});
return (
<>
<div className="flex flex-col gap-4">
<label className="label flex items-center gap-2">
<input type="checkbox" className="checkbox" checked={open} onChange={(e) => setOpen(e.currentTarget.checked)} />
<span className="label-text">Open Panel</span>
</label>
<label className="label">
<span className="label-text">Width:</span>
<input type="number" className="input" value={size.width} onChange={(e) => setSize({ ...size, width: Number(e.target.value) })} />
</label>
<label className="label">
<span className="label-text">Height:</span>
<input
type="number"
className="input"
value={size.height}
onChange={(e) => setSize({ ...size, height: Number(e.target.value) })}
/>
</label>
</div>
<FloatingPanel
open={open}
onOpenChange={(details) => setOpen(details.open)}
size={size}
onSizeChange={(details) => setSize(details.size)}
>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Controlled Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel's open state and size are controlled via the inputs above.</p>
<p>Try changing the values or resizing/closing the panel to see the inputs update.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
</>
);
}This panel's open state and size are controlled via the inputs above.
Try changing the values or resizing/closing the panel to see the inputs update.
<script lang="ts">
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
let open = $state(false);
let size = $state({
width: 400,
height: 300,
});
</script>
<div class="flex flex-col gap-4">
<label class="label flex items-center gap-2">
<input type="checkbox" class="checkbox" bind:checked={open} />
<span class="label-text">Open Panel</span>
</label>
<label class="label">
<span class="label-text">Width:</span>
<input type="number" class="input" bind:value={size.width} />
</label>
<label class="label">
<span class="label-text">Height:</span>
<input type="number" class="input" bind:value={size.height} />
</label>
</div>
<FloatingPanel {open} onOpenChange={(details) => (open = details.open)} {size} onSizeChange={(details) => (size = details.size)}>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Controlled Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon class="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel's open state and size are controlled via the inputs above.</p>
<p>Try changing the values or resizing/closing the panel to see the inputs update.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>Anchor Position
Position the panel relative to another element using the defaultPosition prop.
This panel is centered in the viewport using getAnchorPosition.
The position is calculated based on the boundary rectangle.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, XIcon, MinusIcon, MaximizeIcon, MinimizeIcon } from 'lucide-react';
export default function AnchorPosition() {
return (
<div className="space-y-4">
<FloatingPanel
getAnchorPosition={(ctx) => {
if (!ctx.triggerRect) return { x: 0, y: 0 };
return {
x: ctx.triggerRect.x + ctx.triggerRect.width / 2,
y: ctx.triggerRect.y + ctx.triggerRect.height / 2,
};
}}
>
<FloatingPanel.Trigger className="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Anchored Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel is centered in the viewport using getAnchorPosition.</p>
<p>The position is calculated based on the boundary rectangle.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
</div>
);
}This panel is centered in the viewport using getAnchorPosition.
The position is calculated based on the boundary rectangle.
<script lang="ts">
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<div class="space-y-4">
<FloatingPanel
getAnchorPosition={(ctx) => {
if (!ctx.triggerRect) return { x: 0, y: 0 };
return {
x: ctx.triggerRect.x + ctx.triggerRect.width / 2,
y: ctx.triggerRect.y + ctx.triggerRect.height / 2,
};
}}
>
<FloatingPanel.Trigger class="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Anchored Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon class="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel is centered in the viewport using getAnchorPosition.</p>
<p>The position is calculated based on the boundary rectangle.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
</div>Resize Triggers
Add resize triggers on all sides and corners of the Floating Panel using the axis prop.
This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing from the bottom-right corner.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, MinimizeIcon, XIcon, MinusIcon, MaximizeIcon } from 'lucide-react';
export default function Default() {
return (
<FloatingPanel>
<FloatingPanel.Trigger className="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>
This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing
from the bottom-right corner.
</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="n" />
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="e" />
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="w" />
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="s" />
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="ne" />
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="se" />
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="sw" />
<FloatingPanel.ResizeTrigger className="bg-primary-500/50" axis="nw" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
);
}This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing from the bottom-right corner.
<script>
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<FloatingPanel>
<FloatingPanel.Trigger class="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>
This is a floating panel that can be dragged, resized, minimized, and maximized. Try dragging from the header or resizing from
the bottom-right corner.
</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="n" />
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="e" />
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="w" />
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="s" />
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="ne" />
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="se" />
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="sw" />
<FloatingPanel.ResizeTrigger class="bg-primary-500/50" axis="nw" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>Disable Dragging
Disable dragging by setting the draggable prop to false. The panel will remain in a fixed position but can still be resized.
This panel cannot be dragged - the position is fixed.
However, it can still be resized from the bottom-right corner.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, XIcon, MinusIcon, MaximizeIcon, MinimizeIcon } from 'lucide-react';
export default function DisableDragging() {
return (
<FloatingPanel draggable={false}>
<FloatingPanel.Trigger className="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Fixed Position Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel cannot be dragged - the position is fixed.</p>
<p>However, it can still be resized from the bottom-right corner.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
);
}This panel cannot be dragged - the position is fixed.
However, it can still be resized from the bottom-right corner.
<script lang="ts">
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<FloatingPanel draggable={false}>
<FloatingPanel.Trigger class="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Fixed Position Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon class="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel cannot be dragged - the position is fixed.</p>
<p>However, it can still be resized from the bottom-right corner.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>Disable Resizing
Disable resizing by setting the resizable prop to false. The panel will have a fixed size but can still be dragged.
This panel cannot be resized.
Try dragging the edges - they won't respond.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, XIcon, MinusIcon, MaximizeIcon, MinimizeIcon } from 'lucide-react';
export default function DisableResizing() {
return (
<FloatingPanel resizable={false}>
<FloatingPanel.Trigger className="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Fixed Size Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel cannot be resized.</p>
<p>Try dragging the edges - they won't respond.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
);
}This panel cannot be resized.
Try dragging the edges - they won't respond.
<script lang="ts">
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<FloatingPanel resizable={false}>
<FloatingPanel.Trigger class="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Fixed Size Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon class="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This panel cannot be resized.</p>
<p>Try dragging the edges - they won't respond.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>Direction
Set the text direction (ltr or rtl) using the dir prop.
This is a floating panel with right-to-left (RTL) direction.
You can drag it from the header or resize it from the bottom-right corner.
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
import { GripVerticalIcon, XIcon, MinusIcon, MaximizeIcon, MinimizeIcon } from 'lucide-react';
export default function Dir() {
return (
<FloatingPanel dir="rtl">
<FloatingPanel.Trigger className="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner className="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon className="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon className="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This is a floating panel with right-to-left (RTL) direction.</p>
<p>You can drag it from the header or resize it from the bottom-right corner.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
);
}This is a floating panel with right-to-left (RTL) direction.
You can drag it from the header or resize it from the bottom-right corner.
<script lang="ts">
import GripVerticalIcon from '@lucide/svelte/icons/grip-vertical';
import MaximizeIcon from '@lucide/svelte/icons/maximize';
import MinimizeIcon from '@lucide/svelte/icons/minimize';
import MinusIcon from '@lucide/svelte/icons/minus';
import XIcon from '@lucide/svelte/icons/x';
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<FloatingPanel dir="rtl">
<FloatingPanel.Trigger class="btn preset-filled">Open Panel</FloatingPanel.Trigger>
<Portal>
<FloatingPanel.Positioner class="z-50">
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title>
<GripVerticalIcon class="size-4" />
Floating Panel
</FloatingPanel.Title>
<FloatingPanel.Control>
<FloatingPanel.StageTrigger stage="minimized">
<MinusIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="maximized">
<MaximizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="default">
<MinimizeIcon class="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.CloseTrigger>
<XIcon class="size-4" />
</FloatingPanel.CloseTrigger>
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body>
<p>This is a floating panel with right-to-left (RTL) direction.</p>
<p>You can drag it from the header or resize it from the bottom-right corner.</p>
</FloatingPanel.Body>
<FloatingPanel.ResizeTrigger axis="se" />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>Anatomy
Here’s an overview of how the Floating Panel component is structured in code:
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-react';
export default function Anatomy() {
return (
<FloatingPanel>
<FloatingPanel.Trigger />
<Portal>
<FloatingPanel.Positioner>
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title />
<FloatingPanel.Control>
<FloatingPanel.StageTrigger />
<FloatingPanel.CloseTrigger />
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body />
<FloatingPanel.ResizeTrigger />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>
);
}<script lang="ts">
import { FloatingPanel, Portal } from '@skeletonlabs/skeleton-svelte';
</script>
<FloatingPanel>
<FloatingPanel.Trigger />
<Portal>
<FloatingPanel.Positioner>
<FloatingPanel.Content>
<FloatingPanel.DragTrigger>
<FloatingPanel.Header>
<FloatingPanel.Title />
<FloatingPanel.Control>
<FloatingPanel.StageTrigger />
<FloatingPanel.CloseTrigger />
</FloatingPanel.Control>
</FloatingPanel.Header>
</FloatingPanel.DragTrigger>
<FloatingPanel.Body />
<FloatingPanel.ResizeTrigger />
</FloatingPanel.Content>
</FloatingPanel.Positioner>
</Portal>
</FloatingPanel>API Reference
Unable to load component information for react/floating-panel
Unable to load component information for svelte/floating-panel