AppShell
Layout-only foundations for rail, sidebar, main content, and optional panels.
Click the control to collapse the sidebar
Controls
import {
AppShellMainSlot,
AppShellOverlaySlot,
AppShellPanelSlot,
AppShellRailSlot,
AppShellRoot,
AppShellSidebarSlot,
} from "raft-ui";
<AppShellRoot>
<AppShellRailSlot>...</AppShellRailSlot>
<AppShellSidebarSlot>...</AppShellSidebarSlot>
<AppShellMainSlot overlay>
...
<AppShellOverlaySlot>...</AppShellOverlaySlot>
</AppShellMainSlot>
<AppShellPanelSlot>...</AppShellPanelSlot>
</AppShellRoot>AppShell hides the rail and sidebar and switches to a column below md. Keep the active page in AppShellMainSlot and add mobile navigation with md:hidden.
apps/doc/src/modules/app-shell/compositions/responsive.composition.tsx
export function AppShellResponsiveComposition() {
return (
<AppShellRoot className="min-h-dvh">
<AppShellRailSlot>
<nav className="w-16" aria-label="Workspace navigation">
Rail
</nav>
</AppShellRailSlot>
<AppShellSidebarSlot>
<div className="w-60">Conversation list</div>
</AppShellSidebarSlot>
<AppShellMainSlot>
<div>Conversation</div>
</AppShellMainSlot>
<MobileNavRoot className="order-last md:hidden" aria-label="Primary navigation">
<MobileNavItem selected>
<MobileNavLabel>Messages</MobileNavLabel>
</MobileNavItem>
</MobileNavRoot>
</AppShellRoot>
);
}sidebarCollapsibledefault: falseboolean
When true, coordinates sidebar visibility and measures sidebar width for the main-panel transition.
sidebarOpenboolean
Controlled sidebar visibility when sidebarCollapsible is enabled.
defaultSidebarOpendefault: trueboolean
Initial sidebar visibility for uncontrolled usage.
onSidebarOpenChange(open: boolean) => void
Called when a collapsible sidebar opens or closes.
...propsuseRender.ComponentProps<"div">
Owns the responsive row-to-column layout and top safe-area inset.
| Prop | Type | Default | Description |
|---|---|---|---|
sidebarCollapsible | boolean | false | When true, coordinates sidebar visibility and measures sidebar width for the main-panel transition. |
sidebarOpen | boolean | — | Controlled sidebar visibility when sidebarCollapsible is enabled. |
defaultSidebarOpen | boolean | true | Initial sidebar visibility for uncontrolled usage. |
onSidebarOpenChange | (open: boolean) => void | — | Called when a collapsible sidebar opens or closes. |
...props | useRender.ComponentProps<"div"> | — | Owns the responsive row-to-column layout and top safe-area inset. |
...propsuseRender.ComponentProps<"aside">
Desktop rail column by default. Mount a separate instance with className for mobile bottom navigation; visibility stays caller-owned.
| Prop | Type | Default | Description |
|---|---|---|---|
...props | useRender.ComponentProps<"aside"> | — | Desktop rail column by default. Mount a separate instance with className for mobile bottom navigation; visibility stays caller-owned. |
overlaydefault: falseboolean
Provides the positioning context for an AppShellOverlaySlot rendered inside the main region.
...propsuseRender.ComponentProps<"main">
Flexible primary content region. In a collapsible desktop layout, mount it inside a relative main panel so it can expand over the sidebar.
| Prop | Type | Default | Description |
|---|---|---|---|
overlay | boolean | false | Provides the positioning context for an AppShellOverlaySlot rendered inside the main region. |
...props | useRender.ComponentProps<"main"> | — | Flexible primary content region. In a collapsible desktop layout, mount it inside a relative main panel so it can expand over the sidebar. |
...propsuseRender.ComponentProps<"div">
Layout-only overlay region for temporarily covering the primary content without changing the column layout. Its child owns the surface and edges.
| Prop | Type | Default | Description |
|---|---|---|---|
...props | useRender.ComponentProps<"div"> | — | Layout-only overlay region for temporarily covering the primary content without changing the column layout. Its child owns the surface and edges. |
...propsuseRender.ComponentProps<"aside">
Optional secondary column. Place it in a caller-owned ResizablePanel when the user can adjust the split; the caller owns its width and surface.
| Prop | Type | Default | Description |
|---|---|---|---|
...props | useRender.ComponentProps<"aside"> | — | Optional secondary column. Place it in a caller-owned ResizablePanel when the user can adjust the split; the caller owns its width and surface. |