DefaultSidebar
DefaultSidebar is the built-in sidebar used by SidebarLayout. It has two modes:
- Auto-generation mode — omit
childrenand it renders navigation from your AppShell modules and resources. - Composition mode — pass
childrenand build the menu yourself withSidebarItem,SidebarGroup,SidebarSeparator, and the low-levelSidebarMenuItem/SidebarMenuButtonprimitives.
Also available as
SidebarLayout.DefaultSidebar. The namespaced form is preferred for discoverability; the top-levelDefaultSidebarexport is kept for backwards compatibility.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
header | React.ReactNode | built-in | Replaces the sidebar header content. |
footer | React.ReactNode | - | Footer content rendered after the navigation area. |
children | React.ReactNode | - | When provided, enables composition mode and disables auto-generation. |
hideHeader | boolean | false | Hides the sidebar's own header row. Useful when a full-width top bar already owns the app title/toggle. |
hideSearch | boolean | false | Hides the built-in Search entry that opens the Command Palette. |
iconRail | boolean | false | Collapses to a persistent icon rail instead of sliding fully off-canvas. |
Basic usage
import { SidebarLayout } from "@tailor-platform/app-shell";
function Layout() {
return <SidebarLayout.DefaultSidebar />;
}Composition mode
import {
SidebarGroup,
SidebarItem,
SidebarLayout,
SidebarSeparator,
} from "@tailor-platform/app-shell";
function Layout() {
return (
<SidebarLayout.DefaultSidebar>
<SidebarItem to="/" />
<SidebarSeparator />
<SidebarGroup title="Main">
<SidebarItem to="/dashboard" />
<SidebarItem to="/orders" />
</SidebarGroup>
</SidebarLayout.DefaultSidebar>
);
}Search entry
The built-in Search entry opens AppShell's CommandPalette. It is rendered in both auto-generated and composed navigation.
Hide it only when search is already exposed elsewhere, such as a dedicated top-bar control:
<SidebarLayout.DefaultSidebar hideSearch />Icon-rail behavior
With iconRail, collapsing the sidebar keeps icons visible at every width:
- on desktop, the sidebar collapses to a narrow persistent rail
- on mobile, the rail stays visible and its toggle opens the full sidebar as a slide-in drawer
- grouped items reveal child pages from the collapsed icon via a flyout popover
- items without children show their label in a tooltip
GlobalHeaderLayout bakes this mode in through GlobalHeaderLayout.DefaultSidebar.
Working with a global top bar
When the app title and primary toggle live in a full-width top bar, hide the sidebar's own header:
<SidebarLayout topBar={<MyGlobalTopBar />} sidebar={<SidebarLayout.DefaultSidebar hideHeader />} />Custom footer
function UserProfile() {
return (
<div className="border-t p-4">
<p className="text-sm font-medium">Ada Lovelace</p>
<button type="button" className="mt-2 text-sm text-muted-foreground">
Logout
</button>
</div>
);
}
<SidebarLayout.DefaultSidebar footer={<UserProfile />} />;Low-level custom items
When SidebarItem is too opinionated, compose a custom row with the exported primitives:
import { SidebarLayout, SidebarMenuButton, SidebarMenuItem } from "@tailor-platform/app-shell";
import { BellIcon } from "lucide-react";
<SidebarLayout.DefaultSidebar>
<SidebarMenuItem>
<SidebarMenuButton
render={<button type="button" />}
onClick={() => openNotifications()}
tooltip="Notifications"
>
<BellIcon className="size-4" />
<span>Notifications</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarLayout.DefaultSidebar>;Related
- SidebarLayout - layout wrapper for sidebar + content
- GlobalHeaderLayout - opinionated app-wide header mode
- SidebarItem - individual navigation links
- SidebarGroup - collapsible navigation groups
- Sidebar Navigation - navigation concepts and composition patterns