This component no longer exists. It was in ericts-ui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-15 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Expanding Panel
ericts-ui/expanding-panelRemovedComponent
A floating panel that grows from a compact icon trigger and holds arbitrary content.
Live preview
live · rendered by the registry
Rendered by ericts-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.ericts.com/r/expanding-panel.jsonSource
1"use client";23import { ChevronsUpDown } from "lucide-react";4import { AnimatePresence, motion, useReducedMotion } from "motion/react";5import * as React from "react";67import { cn } from "@/lib/utils";89const PANEL_TRANSITION = {10 type: "spring",11 duration: 0.24,12 bounce: 0,13} as const;14const CONTENT_TRANSITION = {15 duration: 0.2,16 ease: [0.16, 1, 0.3, 1],17} as const;18const REDUCED_TRANSITION = { duration: 0 } as const;19// Single source of truth for the panel's height cap. Applied to the content20// region so consumers can add a scroll area / pinned footer without knowing it.21const CONTENT_MAX_HEIGHT =22 "var(--expanding-panel-max-height, min(15.5rem, calc(100dvh - 8rem)))";2324type ExpandingPanelContextValue = {25 open: boolean;26 setOpen: (open: boolean) => void;27};2829const ExpandingPanelContext =30 React.createContext<ExpandingPanelContextValue | null>(null);3132/**33 * Access the expanding panel's open state from within its `children`, e.g. to34 * collapse the panel after an action. Throws when used outside the component.35 */36export function useExpandingPanel() {37 const context = React.useContext(ExpandingPanelContext);3839 if (!context) {40 throw new Error(41 "useExpandingPanel must be used within an <ExpandingPanel>.",42 );43 }4445 return context;46}4748export type ExpandingPanelClassNames = {49 panel?: string;50 content?: string;51 trigger?: string;52};5354export type ExpandingPanelProps = Omit<55 React.ComponentPropsWithoutRef<"aside">,56 "children"57> & {58 open?: boolean;59 defaultOpen?: boolean;60 onOpenChange?: (open: boolean) => void;61 triggerIcon?: React.ReactNode;62 openLabel?: string;63 closeLabel?: string;64 closeOnEscape?: boolean;65 closeOnOutsideClick?: boolean;66 classNames?: ExpandingPanelClassNames;67 children?: React.ReactNode;68};6970/**71 * A floating panel that grows in width and height from a compact icon trigger72 * in its top-right corner. It is intentionally content-agnostic.73 *74 * The panel is bounded by `--expanding-panel-width` and75 * `--expanding-panel-max-height` and clips overflow, so the morph never runs76 * off-screen. The content region is a flex column capped at that height, so77 * tall content can add a `flex-1` scroll area (and, e.g., a `shrink-0` pinned78 * footer) without re-declaring the cap.79 *80 * The trigger overlays the top-right corner; content that reaches it should81 * clear it with `pr-[var(--expanding-panel-trigger-inset)]` (defaults to the82 * 2rem trigger size).83 */84export function ExpandingPanel({85 open,86// … truncated
What it pulls in
npm packages
Files it writes
More from ericts-ui
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Adaptive Draweradaptive-drawer | ericts-ui | Components | Free | 2 deps | |
| Adaptive Switchadaptive-switch | ericts-ui | Components | Free | 2 deps | |
| Check Markcheck-mark | ericts-ui | Components | Free | no deps · 2 files | |
| Context Cursorcontext-cursor | ericts-ui | Components | Free | 1 dep | |
| Copy Buttoncopy-button | ericts-ui | Components | Free | 2 deps | |
| Expandable Dialogexpandable-dialog | ericts-ui | Components | Free | 1 dep | |
| Expandable Panelexpandable-panel | ericts-ui | Components | Free | 2 deps | |
| Expandable Segmented Tabsexpandable-segmented-tabs | ericts-ui | Components | Free | 1 dep |
