From b423eda17528348aa68bd25a92b7bafd6c3544cc Mon Sep 17 00:00:00 2001 From: Colin Reilly Date: Fri, 17 Apr 2026 18:30:48 -0700 Subject: [PATCH] feat(apollo-vertex): docs, templates and preview fixes - Add SidebarTemplate and SidebarTemplateDynamic for sidebar docs - Update ShellRoot template - Update sidebar and shell documentation pages - Fix z-index stacking in preview-full-screen (initial={false} for SSR) - Include shell.tsx with subItems type for ShellNavItem Co-Authored-By: Claude Opus 4.6 --- .../app/_components/preview-full-screen.tsx | 8 +- .../app/components/sidebar/page.mdx | 32 ++- .../apollo-vertex/app/patterns/shell/page.mdx | 14 +- apps/apollo-vertex/registry/shell/shell.tsx | 7 + .../templates/SidebarTemplate.tsx | 200 ++++++++++++++++++ .../templates/SidebarTemplateDynamic.tsx | 11 + .../templates/shell/ShellRoot.tsx | 10 +- 7 files changed, 267 insertions(+), 15 deletions(-) create mode 100644 apps/apollo-vertex/templates/SidebarTemplate.tsx create mode 100644 apps/apollo-vertex/templates/SidebarTemplateDynamic.tsx diff --git a/apps/apollo-vertex/app/_components/preview-full-screen.tsx b/apps/apollo-vertex/app/_components/preview-full-screen.tsx index a20ea3545..95377284f 100644 --- a/apps/apollo-vertex/app/_components/preview-full-screen.tsx +++ b/apps/apollo-vertex/app/_components/preview-full-screen.tsx @@ -31,7 +31,9 @@ export function PreviewFullScreen({ style={{ height }} > {!isOpen && ( -
{children}
+
+ {children} +
)} -
{children}
+
+ {children} +
); diff --git a/apps/apollo-vertex/app/components/sidebar/page.mdx b/apps/apollo-vertex/app/components/sidebar/page.mdx index 542542fa6..97415b083 100644 --- a/apps/apollo-vertex/app/components/sidebar/page.mdx +++ b/apps/apollo-vertex/app/components/sidebar/page.mdx @@ -1,12 +1,13 @@ +import { SidebarExampleTemplate } from '@/templates/SidebarTemplateDynamic'; +import { PreviewFullScreen } from '@/app/_components/preview-full-screen'; + # Sidebar A composable, themeable and customizable sidebar component. -
-

- The Sidebar component is a complex layout component. See the usage example below for implementation details. -

-
+ + + ## Installation @@ -42,19 +43,28 @@ import { ## Features -- **Collapsible** - Can collapse to icons only -- **Composable** - Build your own sidebar structure -- **Themeable** - Supports dark mode and custom themes -- **Responsive** - Works well on mobile and desktop -- **Keyboard accessible** - Full keyboard navigation support +- **Collapsible** - Can collapse to icons only with `collapsible="icon"` +- **Composable** - Build your own sidebar structure with provided primitives +- **Themeable** - Supports dark mode and custom themes via CSS variables +- **Responsive** - Renders as a sheet on mobile, fixed sidebar on desktop +- **Keyboard accessible** - Toggle with `⌘B`, full keyboard navigation support ## Components - `SidebarProvider` - Provides context for sidebar state - `Sidebar` - The main sidebar container - `SidebarHeader` - Header section of the sidebar -- `SidebarContent` - Main content area +- `SidebarContent` - Main scrollable content area - `SidebarFooter` - Footer section - `SidebarGroup` - Groups related items +- `SidebarGroupLabel` - Label for a group +- `SidebarGroupContent` - Content wrapper for a group - `SidebarMenu` - Navigation menu +- `SidebarMenuButton` - Clickable menu button with tooltip support - `SidebarMenuItem` - Individual menu items +- `SidebarMenuSub` - Sub-menu container for nested navigation +- `SidebarMenuSubButton` - Sub-menu item button +- `SidebarMenuSubItem` - Sub-menu item wrapper +- `SidebarInset` - Main content area adjacent to the sidebar +- `SidebarTrigger` - Button to toggle sidebar open/closed +- `SidebarRail` - Narrow rail for hover-to-expand interaction diff --git a/apps/apollo-vertex/app/patterns/shell/page.mdx b/apps/apollo-vertex/app/patterns/shell/page.mdx index 6bdd2e181..73eb2a884 100644 --- a/apps/apollo-vertex/app/patterns/shell/page.mdx +++ b/apps/apollo-vertex/app/patterns/shell/page.mdx @@ -19,6 +19,10 @@ Use the `variant="minimal"` prop to render a horizontal header layout instead of ## Features +- **Collapsible Sidebar**: Icon-only collapsed mode with smooth spring animations, built on the shadcn sidebar primitives +- **Sub-Navigation**: Collapsible menu items with nested sub-items that auto-expand when active +- **Collapsed Menu Handling**: Clicking a collapsible item while collapsed expands the sidebar and opens the submenu +- **Custom Logo**: Support for company logos with separate light/dark mode variants - **Optional OAuth2 Authentication**: Plug-and-play authorization code flow with PKCE - **Theme Toggle**: Built-in light/dark mode support - **Language Toggle**: Built-in language switcher for internationalization @@ -40,7 +44,15 @@ import { ApolloShell } from '@/components/ui/shell'; const navItems = [ { path: '/dashboard', label: 'dashboard', icon: Home }, - { path: '/settings', label: 'settings', icon: Settings }, + { + path: '/settings', + label: 'settings', + icon: Settings, + subItems: [ + { path: '/settings', label: 'settings' }, + { path: '/settings/appearance', label: 'appearance' }, + ], + }, ]; function App() { diff --git a/apps/apollo-vertex/registry/shell/shell.tsx b/apps/apollo-vertex/registry/shell/shell.tsx index b7b9a6bb1..b01d6392d 100644 --- a/apps/apollo-vertex/registry/shell/shell.tsx +++ b/apps/apollo-vertex/registry/shell/shell.tsx @@ -12,12 +12,19 @@ export interface CompanyLogo { url: string; darkUrl?: string; alt: string; + isCustom?: boolean; +} + +export interface ShellSubNavItem { + path: string; + label: TranslationKey; } export interface ShellNavItem { path: string; label: TranslationKey; icon: LucideIcon; + subItems?: ShellSubNavItem[]; } export interface ApolloShellProps extends PropsWithChildren { diff --git a/apps/apollo-vertex/templates/SidebarTemplate.tsx b/apps/apollo-vertex/templates/SidebarTemplate.tsx new file mode 100644 index 000000000..fcea77341 --- /dev/null +++ b/apps/apollo-vertex/templates/SidebarTemplate.tsx @@ -0,0 +1,200 @@ +"use client"; + +import { + ChevronDown, + Home, + Inbox, + LayoutDashboard, + PanelLeft, + Search, + Settings, + User2, +} from "lucide-react"; +import { useState } from "react"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarGroup, + SidebarGroupContent, + SidebarGroupLabel, + SidebarHeader, + SidebarInset, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarMenuSub, + SidebarMenuSubButton, + SidebarMenuSubItem, + SidebarProvider, + useSidebar, +} from "@/components/ui/sidebar"; +import { cn } from "@/lib/utils"; + +const mainNavItems = [ + { label: "Home", icon: Home }, + { label: "Inbox", icon: Inbox }, + { label: "Search", icon: Search }, +]; + +const settingsSubItems = [ + { label: "General" }, + { label: "Appearance" }, + { label: "Notifications" }, +]; + +function SidebarHeaderContent() { + const { toggleSidebar, state } = useSidebar(); + const isCollapsed = state === "collapsed"; + + return ( +
+ {!isCollapsed && ( + <> +
+
+ +
+ Acme Inc +
+ + + )} + {isCollapsed && ( + + )} +
+ ); +} + +export function SidebarExample() { + const [active, setActive] = useState("Home"); + const [settingsOpen, setSettingsOpen] = useState(false); + + return ( + + + + + + + + + Navigation + + + {mainNavItems.map((item) => ( + + { + setActive(item.label); + setSettingsOpen(false); + }} + > + + {item.label} + + + ))} + + + + + + + Settings + + + + + + {settingsSubItems.map((sub) => { + const subKey = `Settings: ${sub.label}`; + return ( + + setActive(subKey)} + > + {sub.label} + + + ); + })} + + + + + + + + + + + + + + + John Doe + + + + + + + +
+

{active}

+

+ Click a nav item or collapse the sidebar +

+
+
+
+ ); +} diff --git a/apps/apollo-vertex/templates/SidebarTemplateDynamic.tsx b/apps/apollo-vertex/templates/SidebarTemplateDynamic.tsx new file mode 100644 index 000000000..4b2b37254 --- /dev/null +++ b/apps/apollo-vertex/templates/SidebarTemplateDynamic.tsx @@ -0,0 +1,11 @@ +"use client"; + +import dynamic from "next/dynamic"; + +export const SidebarExampleTemplate = dynamic( + () => + import("./SidebarTemplate").then((mod) => ({ + default: mod.SidebarExample, + })), + { ssr: false }, +); diff --git a/apps/apollo-vertex/templates/shell/ShellRoot.tsx b/apps/apollo-vertex/templates/shell/ShellRoot.tsx index a63fd2893..5a9d3d55d 100644 --- a/apps/apollo-vertex/templates/shell/ShellRoot.tsx +++ b/apps/apollo-vertex/templates/shell/ShellRoot.tsx @@ -8,7 +8,15 @@ const navItems: ShellNavItem[] = [ { path: "/preview/shell/projects", label: "projects", icon: FolderOpen }, { path: "/preview/shell/analytics", label: "analytics", icon: BarChart3 }, { path: "/preview/shell/team", label: "team", icon: Users }, - { path: "/preview/shell/settings", label: "settings", icon: Settings }, + { + path: "/preview/shell/settings", + label: "settings", + icon: Settings, + subItems: [ + { path: "/preview/shell/settings", label: "settings" }, + { path: "/preview/shell/team", label: "team" }, + ], + }, ]; const minimalNavItems: ShellNavItem[] = [