Slide Over Panel
A non-modal narrow floating panel that can be dragged and magnetically snapped to either side, and flicked away to collapse into an edge handle — springs tracking the pointer throughout.
npx shadcn@latest add https://webberui.com/r/slide-over-panel.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<SlideOverPanel />
Installation
npx shadcn@latest add https://webberui.com/r/slide-over-panel.jsonOr, once registries are configured in components.json, install it as @webberui/slide-over-panel.
Usage
The panel is absolute-positioned, and with anchor="container" (the default) it hugs the nearest positioned ancestor, so make sure the outer container is position: relative:
import { SlideOverPanel } from "@/components/ui/slide-over-panel";
<div className="relative h-[480px] overflow-hidden">
{/* your main content */}
<SlideOverPanel title="Recent activity">
<p>Panel content…</p>
</SlideOverPanel>
</div>To float the panel over the whole viewport, use anchor="viewport" instead (which uses fixed positioning and needs no positioned ancestor).
Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | Panel content |
title | React.ReactNode | — | Panel heading, which also serves as the source of the accessible label |
side | "left" | "right" | — | Controlled snap side |
defaultSide | "left" | "right" | "right" | Uncontrolled default snap side |
onSideChange | (side) => void | — | Snap-side change callback |
collapsed | boolean | — | Controlled collapsed state |
defaultCollapsed | boolean | false | Uncontrolled default collapsed state |
onCollapsedChange | (collapsed) => void | — | Collapsed-state change callback |
panelWidth | number | 300 | Width of the panel body (px, excluding the handle) |
anchor | "container" | "viewport" | "container" | Positioning basis |
label | string | — | Accessible label; falls back to title when not provided |
className | string | — | Appended to the panel body's className |
How it works
- Magnetic snapping: after a drop, whichever half of the container the panel's center lands in is the side it springs to and expands on.
- Flick to collapse: if the horizontal velocity on release exceeds the threshold (600 px/s), it collapses into an edge handle in the direction of the flick; pulling the handle back out expands it again.
- Tracks the pointer throughout: dragging, spring back, snapping, and collapsing all run on the same spring set, so it settles crisply rather than stiffly.
- Two controlled axes: both
sideandcollapsedsupport controlled and uncontrolled modes, and each can be controlled independently.
Accessibility
- The panel is a
role="region"usingtitleorlabelas itsaria-label. - The edge handle is a native
button:Enter/Spacetoggle collapse, and←/→snap it to the left or right side and expand it, filling the gap where dragging cannot be done from the keyboard. - The handle reflects the expanded state through
aria-expanded; when collapsed, the panel body carriesaria-hiddenand interaction is disabled. - The panel is non-modal: it does not lock scrolling and does not intercept interaction with the content beneath (
pointer-eventsonly apply to the panel itself). - When the user has "reduce motion" enabled at the system level, dragging is disabled and the spring offsets are replaced with instant positioning.
Zen Mode Shell
A focus-mode shell: one click and the sidebar, top bar, and auxiliary panel fade out and slide away in timeline order while the main content eases back to center and scales up; exiting reverses the choreography and restores the whole shell.
Control Center Panel
A grid of glass control modules; long-press any tile and it springs open in place into a fine-grained control card (slider, segmented toggle) while the background blurs and recedes, springing back on release.