Gantry
App shell block: a workspace switcher, sectioned sidebar nav with height-animated nested groups, an active pill that slides between items, Tally badges that roll on change, a pinned footer card and a user menu; the sidebar springs between full width and an icon rail (toggle or `[`) with label flyouts and nested flyout menus; the topbar carries breadcrumbs, a ⌘K manifest command palette and a tocsin notifications bell; under 720px of container width the sidebar becomes a swipe-to-close drawer with a focus trap. Controlled collapsed / activeId, skip link and a <main> landmark.
The preview is live. The source is Pro.
One purchase, lifetime access: every pro component's source, CLI install with your own registry token, and all future drops.
Installation
CLI
npx shadcn@latest add @crucible/gantryManual — install dependencies, then copy the source
npm install motionProps
| Prop | Type | Default | Description |
|---|---|---|---|
| brand | string | "Lumen" | Product name — shown under the workspace name when the workspace has no plan. |
| logo | React.ReactNode | Square mark used for workspaces without their own logo. | |
| workspaces | GantryWorkspace[] | three sample workspaces | Workspaces in the switcher. With one workspace (and no onCreateWorkspace) the switcher is a static header. |
| workspaceId | string | Controlled current workspace id. | |
| defaultWorkspaceId | string | the first workspace | Initial workspace when uncontrolled. |
| onWorkspaceChange | (id: string) => void | Fires when a workspace is picked from the switcher. | |
| onCreateWorkspace | () => void | a no-op in the sample | Shows "Create workspace" in the switcher. |
| sections | GantrySection[] | a sample product nav | Sidebar nav, grouped into sections. |
| activeId | string | Controlled active nav item id. | |
| defaultActiveId | string | "relaunch" (sample) or the first item | Initial active id when uncontrolled. |
| onNavigate | (id: string, item: GantryNavItem) => void | Fires when a nav item (or a "Go to" command) is chosen. | |
| collapsed | boolean | Controlled rail mode. Pair with onCollapsedChange. | |
| defaultCollapsed | boolean | false | Initial rail mode when uncontrolled. |
| onCollapsedChange | (collapsed: boolean) => void | Fires whenever rail mode changes (toggle button, [ key, handle). | |
| user | GantryUser | a sample user | Signed-in user (bottom chip). |
| userMenu | GantryMenuItem[] | Profile / Settings / Sign out | User menu entries. |
| onUserMenuSelect | (id: string) => void | Fires when a user-menu entry is chosen. | |
| breadcrumbs | GantryBreadcrumb[] | derived: workspace / parent / active item | Topbar breadcrumbs. |
| footer | React.ReactNode | a sample usage card | Pinned card above the user chip (usage meter, upgrade CTA…). null hides it. |
| actions | React.ReactNode | Extra topbar controls, rendered before the notifications bell. | |
| notifications | Omit<TocsinProps, "ref" | "inline"> | false | Props forwarded to the tocsin notifications bell, or false to hide it. Its accent defaults to accentColor. | |
| commands | ManifestItem[] | Extra ⌘K palette commands (forwarded to manifest). "Go to" commands for every nav item are always included. | |
| searchLabel | string | "Search…" | Search trigger label. |
| searchPlaceholder | string | "Search pages and commands…" | Placeholder inside the palette. |
| hotkeys | boolean | true | Global shortcuts: ⌘K opens search, [ toggles the sidebar (ignored while typing). |
| children | React.ReactNode | a sample placeholder page | Page content, rendered in the scrollable <main> region. |
| mainClassName | string | Classes for the scrollable <main> region. | |
| accentColor | string | "#c4b5fd" | The single accent: active pill bar, badges, focus rings, current workspace tile. Hex gets auto black/white ink. |
| ref | React.Ref<GantryHandle> | Imperative handle — collapse(), expand(), toggle(), openSearch(), replay(). | |
| className | string | Classes for the root (give it a height, e.g. h-[600px] or h-dvh). | |
| style | React.CSSProperties | Inline styles for the root. |
Honors prefers-reduced-motion with a designed static fallback, and passes className through.