import { useEffect, type ReactNode } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import {
Bot,
CircleDot,
House,
Inbox,
LayoutDashboard,
SquarePen,
Users,
} from "lucide-react";
import { BreadcrumbBar } from "@/components/BreadcrumbBar";
import { CommandPalette } from "@/components/CommandPalette";
import { CompanySwitcher } from "@/components/CompanySwitcher";
import { KeyboardShortcutsCheatsheetContent } from "@/components/KeyboardShortcutsCheatsheet";
import { MobileBottomNav } from "@/components/MobileBottomNav";
import { PageTabBar } from "@/components/PageTabBar";
import { Sidebar } from "@/components/Sidebar";
import { SidebarAccountMenu } from "@/components/SidebarAccountMenu";
import { SidebarCompanyMenu } from "@/components/SidebarCompanyMenu";
import { StatusBadge } from "@/components/StatusBadge";
import { Badge } from "@/components/ui/badge";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/components/ui/command";
import { Tabs } from "@/components/ui/tabs";
import { BreadcrumbProvider, useBreadcrumbs, type Breadcrumb } from "@/context/BreadcrumbContext";
import { useNavigate } from "@/lib/router";
import { cn } from "@/lib/utils";
import {
storybookAgents,
storybookIssues,
storybookProjects,
storybookSidebarBadges,
} from "../fixtures/paperclipData";
function Section({
eyebrow,
title,
children,
}: {
eyebrow: string;
title: string;
children: ReactNode;
}) {
return (
);
}
function RouteSetter({ to }: { to: string }) {
const navigate = useNavigate();
useEffect(() => {
navigate(to, { replace: true });
}, [navigate, to]);
return null;
}
function SidebarShell({ collapsed = false }: { collapsed?: boolean }) {
return (
);
}
function BreadcrumbScenario({ breadcrumbs }: { breadcrumbs: Breadcrumb[] }) {
const { setBreadcrumbs } = useBreadcrumbs();
useEffect(() => {
setBreadcrumbs(breadcrumbs);
}, [breadcrumbs, setBreadcrumbs]);
return (
);
}
function BreadcrumbSnapshot({ breadcrumbs }: { breadcrumbs: Breadcrumb[] }) {
return (
);
}
const tabItems = [
{ value: "overview", label: "Overview" },
{ value: "issues", label: "Issues" },
{ value: "runs", label: "Runs" },
{ value: "approvals", label: "Approvals" },
{ value: "budget", label: "Budget" },
{ value: "activity", label: "Activity" },
{ value: "settings", label: "Settings" },
{ value: "history", label: "History" },
];
const mobileNavItems = [
{ label: "Home", icon: House },
{ label: "Issues", icon: CircleDot },
{ label: "Create", icon: SquarePen },
{ label: "Agents", icon: Users },
{ label: "Inbox", icon: Inbox, badge: storybookSidebarBadges.inbox },
];
function MobileBottomNavActiveStateMatrix() {
return (
{mobileNavItems.map((activeItem) => (
{mobileNavItems.map((item) => {
const Icon = item.icon;
const active = item.label === activeItem.label;
return (
{item.badge ? (
{item.badge}
) : null}
{item.label}
);
})}
))}
);
}
function CommandResultsSurface() {
return (
Create new issue
C
{storybookIssues.slice(0, 2).map((issue) => (
{issue.identifier}
{issue.title}
))}
{storybookAgents.map((agent) => (
{agent.name}
{agent.role}
))}
{storybookProjects.map((project) => (
{project.name}
))}
);
}
function CommandEmptySurface() {
return (
No results found.
);
}
function NavigationLayoutStories() {
return (
Navigation and layout
Sidebar, command, tabs, and mobile chrome
Fixture-backed navigation states for the board shell: company switching, dense work navigation,
breadcrumbs, command discovery, and mobile entry points.
fixture backed
company scoped
responsive chrome
undefined}
version="0.3.1"
/>
undefined} />
undefined} />
);
}
const meta = {
title: "Product/Navigation & Layout",
component: NavigationLayoutStories,
parameters: {
docs: {
description: {
component:
"Navigation and layout stories cover the board shell components that orient operators across companies, work surfaces, command search, breadcrumbs, tabs, and mobile navigation.",
},
},
},
} satisfies Meta;
export default meta;
type Story = StoryObj;
export const BoardChromeMatrix: Story = {};