Side Panel

A panel beside the page for details, a form or anything else, full height.

View as Markdown
Activity
const slot = useRef<HTMLDivElement>(null);
<div {...stylex.props(styles.row)}>  <Page onSelect={setSelected} />  <SidePanelSlot ref={slot} />  <SidePanel    onOpenChange={(open) => !open && setSelected(null)}    open={selected !== null}  >    <SidePanelContent container={slot}>      <SidePanelHeader>        <SidePanelTitle>Signed in</SidePanelTitle>      </SidePanelHeader>      <SidePanelBody>…</SidePanelBody>      <SidePanelFooter>…</SidePanelFooter>    </SidePanelContent>  </SidePanel></div>;

Installation

$ npx shadcn@latest add @constella/side-panel

Usage

import {  SidePanel,  SidePanelBody,  SidePanelContent,  SidePanelDescription,  SidePanelFooter,  SidePanelHeader,  SidePanelSlot,  SidePanelTitle,} from "@/components/primitives/side-panel";

Put a SidePanelSlot after the whole page, header included, in a flex row, so the panel runs the full height of it. Pass its ref to SidePanelContent as container.

The panel opens there, so the content narrows beside it instead of being covered. It's a non-modal dialog: the content stays usable, and Escape or Close shuts it.

The header is one row, so a SidePanelDescription goes first in the body. It names the panel's description for screen readers, as a dialog's does.

On a narrow window, show the same details in a Sheet instead.

Composition

SidePanelSlotSidePanel└── SidePanelContent    ├── SidePanelHeader    │   └── SidePanelTitle    ├── SidePanelBody    │   └── SidePanelDescription    └── SidePanelFooter

API Reference

PartAdds
SidePanelBase UI Dialog, non-modal, not closed by an outside click
SidePanelContentcontainer: the slot's ref; renders the portal and popup
SidePanelHeaderA row sizes.header tall, pinned: the title, any actions, then Close
SidePanelDescriptionMuted text first in the body; the panel's accessible description
SidePanelBodyScrolls on its own
SidePanelFooterPinned below the body

Every part takes sx, applied last. For the rest, see Base UI Dialog.