Navigation and layout

Sidebar Layout

An application-shell layout that coordinates a 4AF sidebar with the main content area.

⠋

Install

npx shadcn@latest add https://4af.selfsimilar.dev/r/sidebar-layout.json

Usage

import { SidebarLayout } from "@/components/ui/sidebar-layout";

<SidebarLayout sidebar={<Sidebar />}>Page content</SidebarLayout>

API

Main export: SidebarLayout

A viewport-height application shell around Sidebar. Navigation and the header stay fixed while the inset content region handles vertical scrolling. The header holds a collapse control on the left, the page title, and optional actions on the right.

It is a separate item from sidebar so the navigation components can be used without this page frame. To fit it inside a box instead of the viewport, override the provider height with className, as the demo on this page does with h-full.

The rail slot

The layout has a second region beside the scrolling content, for a full-height detail panel. It is a sibling of the scroll container rather than a child, so the panel spans the full height and a footer pinned inside it doesn't scroll away with the content.

Nothing renders there until something portals in. The slot is display: contents, so the portalled panel becomes a direct flex child of the row and sets its own width.

useSidebarLayoutRailSlot() returns the slot's mount point, or null when it is unavailable. Prefer the hook to a DOM lookup. SIDEBAR_LAYOUT_RAIL_SLOT_ID is exported for code that cannot access the context.

function DetailRail({ children }: { children: ReactNode }) {
  const slot = useSidebarLayoutRailSlot();
  return slot ? createPortal(children, slot) : null;
}

On this page