@petrarca/sonnet-shell
v0.7.0
Published
Application shell, layout, navigation, auth flow, and imperative API for the Petrarca Sonnet component library
Downloads
297
Readme
@petrarca/sonnet-shell
The application frame of the Petrarca Sonnet component library. You write feature areas as modules; the shell composes them into navigation, routes, a command menu and a set of surfaces any module can reach imperatively.
What it provides
A module system. A ShellModule declares its routes, navigation, command
menu entries, side pane and contributions to other modules.
createModuleRegistry aggregates them and derives the navigation zones and the
flattened route list once.
Two navigation layouts. ShellRail, a narrow icon strip with a contextual
sub-nav panel, and ShellSidebar, a single-column sidebar with collapsible
sections. Both read the same module metadata, and IconRail, Sidebar,
SidebarGroup, SidebarItem and SubNavPanel are exported for a custom one.
Shell chrome. RootLayout and AppShell, TopBar, ShellFooter,
ShellVersion, SearchTrigger and UserMenu.
An imperative API. notification, dialog, navigation, panel,
sidePane, fullscreen and events are plain function calls, so a page
reaches a toast, a confirm dialog, a slide-over or another module without prop
drilling.
Capability gating. A module can declare what it requires; the application
supplies resolveCapability and a policy decides whether an unmet module is
hidden, disabled or shown with an explanation.
Auth screens on the ./auth subpath: Login, ProtectedRoute and
OrgSelection. Prop-driven, with no auth logic of their own -- organization
choice is the orgs and onSelectOrg props of Login.
Install
pnpm add @petrarca/sonnet-shell @petrarca/sonnet-ui @petrarca/sonnet-core| Peer | Range | Needed for |
|---|---|---|
| react, react-dom | >=19 | Everything |
| react-router-dom | >=7 | Routing, SidebarItem, ProtectedRoute; the shell is built on the router, not adapted to it |
| tailwindcss | >=3 | The classes the shell renders |
lucide-react and sonner arrive as regular dependencies.
Usage
Declare modules, build a registry, mount RootLayout as a layout route.
import { createBrowserRouter, RouterProvider, Navigate } from "react-router-dom";
import { RootLayout, createModuleRegistry } from "@petrarca/sonnet-shell";
import type { ShellConfig } from "@petrarca/sonnet-shell";
import home from "@/modules/home";
import widgets from "@/modules/widgets";
const registry = createModuleRegistry([home, widgets]);
const shellConfig: ShellConfig = {
topBar: <TopBarContent />,
};
const router = createBrowserRouter([
{
element: <RootLayout config={shellConfig} registry={registry} />,
children: [
{ index: true, element: <Navigate to="/home" replace /> },
...registry.allRoutes,
],
},
]);
export function AppRouter() {
return <RouterProvider router={router} />;
}A module is a plain object with id, label, icon, basePath, navigation
and routes, plus optional matchPaths, topNav, commands,
contributions, sidePane, layout, useEffects, requires, pinBottom
and hidden. The full contract is in modules.
The shell sizes itself from the document and the library does not set document styles, so the app-level layout CSS in getting started is required -- omitting it is the most common setup failure.
Documentation
- Usage guides -- getting started, modules, navigation, the imperative API, events, capabilities and auth.
- Design docs -- the navigation layout model and module capabilities.
- Workspace documentation -- how the packages layer and the architecture decision records.
License
Apache 2.0. See LICENSE.md.
