{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "page-layouts-02",
  "type": "registry:component",
  "title": "Page Layouts",
  "author": "Toby Belhome",
  "description": "Design organized and intuitive dashboard experiences with Tailwind CSS page layouts. These sections combine sidebars, headers, content areas, and responsive grids to present data clearly. Perfect for SaaS platforms, admin panels, and analytics tools seeking modern, user-friendly, and visually structured interfaces.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "sidebar",
    "separator",
    "button",
    "badge",
    "collapsible",
    "avatar",
    "button",
    "sidebar"
  ],
  "files": [
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/components/app-header.tsx",
      "content": "import * as React from \"react\";\n\nimport { SidebarTrigger } from \"@/components/ui/sidebar\";\nimport { Separator } from \"@/components/ui/separator\";\n\nimport { NavMainHorizontal } from \"./nav-main-horizontal\";\nimport { navigationLinks } from \"./app-sidebar\";\nimport { NavUser } from \"./nav-user\";\nimport { Logo } from \"./logo\";\nimport { BellIcon, MailIcon } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\n\nexport function AppHeader() {\n  return (\n    <header\n      data-slot=\"header\"\n      className=\"flex h-16 shrink-0 items-center justify-between gap-2 px-4 [&_[data-logo=description]]:hidden\">\n      <div className=\"flex grow items-center\">\n        <Logo />\n        <Separator orientation=\"vertical\" className=\"mx-4 data-[orientation=vertical]:h-4\" />\n        <SidebarTrigger className=\"-ml-1 md:hidden\" />\n        <NavMainHorizontal items={navigationLinks} />\n      </div>\n      <div className=\"flex items-center gap-6\">\n        <div className=\"flex items-center gap-2\">\n          <Button size=\"icon-sm\" variant=\"ghost\">\n            <MailIcon />\n          </Button>\n          <Button size=\"icon-sm\" variant=\"ghost\" className=\"relative\">\n            <BellIcon />\n            <Badge className=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1 text-[10px]\">\n              5\n            </Badge>\n          </Button>\n        </div>\n        <NavUser />\n      </div>\n    </header>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/components/app-header.tsx"
    },
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/components/app-sidebar.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { BookOpenIcon, InfoIcon, LifeBuoyIcon } from \"lucide-react\";\n\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarHeader,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem\n} from \"@/components/ui/sidebar\";\nimport { NavMainVertical } from \"./nav-main-vertical\";\nimport { useIsMobile } from \"@/hooks/use-mobile\";\nimport { Logo } from \"./logo\";\n\nexport const navigationLinks = [\n  {\n    title: \"Get Started\",\n    type: \"description\",\n    items: [\n      {\n        url: \"#\",\n        title: \"Dashboard\",\n        description: \"Browse all components in the library.\"\n      },\n      {\n        url: \"#\",\n        title: \"Ecommerce\",\n        description: \"Learn how to use the library.\"\n      },\n      {\n        url: \"#\",\n        title: \"Reports\",\n        description: \"Pre-built layouts for common use cases.\"\n      }\n    ]\n  },\n  {\n    title: \"Apps\",\n    type: \"simple\",\n    items: [\n      { url: \"#\", title: \"Chats\" },\n      { url: \"#\", title: \"Kanban Board\" },\n      { url: \"#\", title: \"Notes\" },\n      { url: \"#\", title: \"Event Calendar\" }\n    ]\n  },\n  {\n    title: \"Pages\",\n    type: \"icon\",\n    items: [\n      { url: \"#\", title: \"Profile Page\", icon: BookOpenIcon },\n      { url: \"#\", title: \"User List\", icon: LifeBuoyIcon },\n      { url: \"#\", title: \"Pricing Page\", icon: InfoIcon }\n    ]\n  }\n];\n\nexport function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {\n  const isMobile = useIsMobile();\n\n  if (!isMobile) return null;\n\n  return (\n    <Sidebar variant=\"inset\" {...props}>\n      <SidebarHeader>\n        <SidebarMenu>\n          <SidebarMenuItem>\n            <SidebarMenuButton size=\"lg\" asChild>\n              <Logo />\n            </SidebarMenuButton>\n          </SidebarMenuItem>\n        </SidebarMenu>\n      </SidebarHeader>\n      <SidebarContent>\n        <NavMainVertical items={navigationLinks} />\n      </SidebarContent>\n    </Sidebar>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/components/app-sidebar.tsx"
    },
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/components/logo.tsx",
      "content": "import * as React from \"react\";\nimport Link from \"next/link\";\n\nexport function Logo() {\n  return (\n    <Link href=\"#\" className=\"flex gap-3\">\n      <img src=\"https://shadcnuikit.com/logo.png\" className=\"size-8 rounded-md\" alt=\"\" />\n      <div\n        data-logo=\"description\"\n        className=\"grid flex-1 text-left text-sm leading-tight md:hidden\">\n        <span className=\"truncate font-medium\">Acme Inc</span>\n        <span className=\"truncate text-xs\">Enterprise</span>\n      </div>\n    </Link>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/components/logo.tsx"
    },
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/components/nav-main-horizontal.tsx",
      "content": "\"use client\";\n\nimport { type LucideIcon } from \"lucide-react\";\nimport {\n  NavigationMenu,\n  NavigationMenuContent,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  NavigationMenuTrigger\n} from \"@/components/ui/navigation-menu\";\nimport { cn } from \"@/lib/utils\";\n\nexport function NavMainHorizontal({\n  items\n}: {\n  items: {\n    title: string;\n    type: string;\n    url?: string;\n    icon?: LucideIcon;\n    items?: {\n      title: string;\n      url: string;\n      description?: string;\n      icon?: LucideIcon;\n    }[];\n  }[];\n}) {\n  return (\n    <NavigationMenu viewport={false} className=\"max-md:hidden\">\n      <NavigationMenuList className=\"gap-2\">\n        {items.map((link, index) => (\n          <NavigationMenuItem key={index}>\n            {link.items?.length ? (\n              <>\n                <NavigationMenuTrigger className=\"text-muted-foreground hover:text-primary bg-transparent px-2 py-1.5 font-medium *:[svg]:-me-0.5 *:[svg]:size-3.5\">\n                  {link.title}\n                </NavigationMenuTrigger>\n                <NavigationMenuContent className=\"data-[motion=from-end]:slide-in-from-right-16! data-[motion=from-start]:slide-in-from-left-16! data-[motion=to-end]:slide-out-to-right-16! data-[motion=to-start]:slide-out-to-left-16! z-50 p-1\">\n                  <ul className={cn(link.type === \"description\" ? \"min-w-64\" : \"min-w-48\")}>\n                    {link.items.map((item, itemIndex) => (\n                      <li key={itemIndex}>\n                        <NavigationMenuLink href={item.url} className=\"py-1.5\">\n                          {/* Display icon if present */}\n                          {link.type === \"icon\" && \"icon\" in item && (\n                            <div className=\"flex items-center gap-2\">\n                              {item.icon && (\n                                <item.icon\n                                  size={16}\n                                  className=\"text-foreground opacity-60\"\n                                  aria-hidden=\"true\"\n                                />\n                              )}\n                              <span>{item.title}</span>\n                            </div>\n                          )}\n\n                          {/* Display label with description if present */}\n                          {link.type === \"description\" && \"description\" in item ? (\n                            <div className=\"space-y-1\">\n                              <div className=\"font-medium\">{item.title}</div>\n                              <p className=\"text-muted-foreground line-clamp-2 text-xs\">\n                                {item.description}\n                              </p>\n                            </div>\n                          ) : (\n                            // Display simple label if not icon or description type\n                            !link.type ||\n                            (link.type !== \"icon\" && link.type !== \"description\" && (\n                              <span>{item.title}</span>\n                            ))\n                          )}\n                        </NavigationMenuLink>\n                      </li>\n                    ))}\n                  </ul>\n                </NavigationMenuContent>\n              </>\n            ) : (\n              <NavigationMenuLink\n                href={link.url}\n                className=\"text-muted-foreground hover:text-primary py-1.5 font-medium\">\n                {link.title}\n              </NavigationMenuLink>\n            )}\n          </NavigationMenuItem>\n        ))}\n      </NavigationMenuList>\n    </NavigationMenu>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/components/nav-main-horizontal.tsx"
    },
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/components/nav-main-vertical.tsx",
      "content": "\"use client\";\n\nimport { ChevronRight, type LucideIcon } from \"lucide-react\";\n\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"@/components/ui/collapsible\";\nimport {\n  SidebarGroup,\n  SidebarGroupLabel,\n  SidebarMenu,\n  SidebarMenuAction,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarMenuSub,\n  SidebarMenuSubButton,\n  SidebarMenuSubItem\n} from \"@/components/ui/sidebar\";\n\nexport function NavMainVertical({\n  items\n}: {\n  items: {\n    title: string;\n    type: string;\n    url?: string;\n    icon?: LucideIcon;\n    items?: {\n      title: string;\n      url: string;\n      description?: string;\n      icon?: LucideIcon;\n    }[];\n  }[];\n}) {\n  return (\n    <>\n      {items.map((item, i) => (\n        <SidebarGroup>\n          <SidebarGroupLabel>{item.title}</SidebarGroupLabel>\n          <SidebarMenu>\n            {item.items?.length ? (\n              <>\n                {item.items?.map((subItem) => (\n                  <SidebarMenuItem key={subItem.title}>\n                    <SidebarMenuButton asChild>\n                      <a href={subItem.url}>\n                        <span>{subItem.title}</span>\n                      </a>\n                    </SidebarMenuButton>\n                  </SidebarMenuItem>\n                ))}\n              </>\n            ) : null}\n          </SidebarMenu>\n        </SidebarGroup>\n      ))}\n    </>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/components/nav-main-vertical.tsx"
    },
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/components/nav-projects.tsx",
      "content": "\"use client\";\n\nimport { type LucideIcon } from \"lucide-react\";\n\nimport {\n  SidebarGroup,\n  SidebarGroupLabel,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem\n} from \"@/components/ui/sidebar\";\nimport Link from \"next/link\";\n\nexport function NavProjects({\n  projects\n}: {\n  projects: {\n    name: string;\n    url: string;\n    icon: LucideIcon;\n  }[];\n}) {\n  return (\n    <SidebarGroup className=\"group-data-[collapsible=icon]:hidden\">\n      <SidebarGroupLabel>Projects</SidebarGroupLabel>\n      <SidebarMenu>\n        {projects.map((item) => (\n          <SidebarMenuItem key={item.name}>\n            <SidebarMenuButton asChild>\n              <Link href={item.url}>\n                <item.icon />\n                <span>{item.name}</span>\n              </Link>\n            </SidebarMenuButton>\n          </SidebarMenuItem>\n        ))}\n      </SidebarMenu>\n    </SidebarGroup>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/components/nav-projects.tsx"
    },
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/components/nav-user.tsx",
      "content": "\"use client\";\n\nimport { BadgeCheck, Bell, CreditCard, LogOut, Sparkles } from \"lucide-react\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger\n} from \"@/components/ui/dropdown-menu\";\nimport { Button } from \"@/components/ui/button\";\n\nconst user = {\n  name: \"shadcn\",\n  email: \"m@example.com\",\n  avatar: \"https://ui.shadcn.com/avatars/shadcn.jpg\"\n};\n\nexport function NavUser() {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"ghost\" className=\"p-0\">\n          <Avatar>\n            <AvatarImage src={user.avatar} alt={user.name} />\n            <AvatarFallback className=\"rounded-lg\">CN</AvatarFallback>\n          </Avatar>\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"min-w-56 rounded-lg\" align=\"end\" sideOffset={4}>\n        <DropdownMenuLabel className=\"p-0 font-normal\">\n          <div className=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n            <Avatar>\n              <AvatarImage src={user.avatar} alt={user.name} />\n              <AvatarFallback className=\"rounded-lg\">CN</AvatarFallback>\n            </Avatar>\n            <div className=\"grid flex-1 text-left text-sm leading-tight\">\n              <span className=\"truncate font-medium\">{user.name}</span>\n              <span className=\"truncate text-xs\">{user.email}</span>\n            </div>\n          </div>\n        </DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <Sparkles />\n            Upgrade to Pro\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <BadgeCheck />\n            Account\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <CreditCard />\n            Billing\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Bell />\n            Notifications\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOut />\n          Log out\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/components/nav-user.tsx"
    },
    {
      "path": "examples/blocks/dashboard-ui/page-layouts/02/page.tsx",
      "content": "import { SidebarInset, SidebarProvider } from \"@/components/ui/sidebar\";\n\nimport { AppSidebar } from \"./components/app-sidebar\";\nimport { AppHeader } from \"./components/app-header\";\n\nexport default function Page() {\n  return (\n    <SidebarProvider>\n      <AppSidebar />\n      <SidebarInset className=\"bg-muted/50\">\n        <AppHeader />\n        <div className=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n          <div className=\"bg-background grid min-h-[100vh] flex-1 place-items-center rounded-xl md:min-h-min\">\n            <span className=\"text-muted-foreground text-sm\">Content goes here</span>\n          </div>\n        </div>\n      </SidebarInset>\n    </SidebarProvider>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/page-layouts/page-layouts.tsx"
    }
  ],
  "meta": {
    "isPro": true
  }
}