layouts
AppShell
Full-height flex column with header, sidebar, main, and footer slots.
AppShell is the chrome you wrap your routed views in. It doesn't take a router opinion, so you can use any navigator under it.
import { AppShell, Sidebar } from "@plyxui/layouts";
<AppShell
header={<TitleBar />}
sidebar={<Sidebar items={items} header={<Brand />} />}
>
<Outlet />
</AppShell>
Props
| Prop | Type | Default |
|---|---|---|
header | ReactNode | - |
sidebar | ReactNode | - |
footer | ReactNode | - |
sidebarWidth | number | 240 |
divider | boolean | true |
The sidebar slot is a single render slot, so consumers can put the plyxui Sidebar there or any custom navigation surface.
Native variant
On native the sidebar slot is dropped; tabs are the right pattern. Use OmniNavigator mode="tabs" from @plyxui/navigator/react-navigation and feed it the same OmniRoute[] you'd render in the web Sidebar.
Composing with the navigator
import { defineRoutes } from "@plyxui/navigator";
import { OmniRouter } from "@plyxui/navigator/react-router";
const routes = defineRoutes([
{ name: "home", path: "/", icon: "home", title: "Home", element: () => <Home /> },
{ name: "subjects", path: "/subjects", icon: "user", title: "Subjects", element: () => <Subjects /> },
{ name: "settings", path: "/settings", icon: "settings", title: "Settings", element: () => <Settings /> },
]);
function Shell() {
return (
<BrowserRouter>
<AppShell sidebar={<Sidebar items={sidebarItems(routes)} />}>
<OmniRouter routes={routes} />
</AppShell>
</BrowserRouter>
);
}
The routes table is the single source of truth for both the sidebar items and the routes themselves.