{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "dashboard-layout",
  "title": "Dashboard Layout",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/dashboard-layout/DashboardLayout.vue",
      "content": "<script setup lang=\"ts\">\nimport { Bell } from 'lucide-vue-next'\nimport Sidebar02 from '@/components/blocks/sidebar-02/Sidebar02.vue'\nimport CommandPalette from '@/components/blocks/CommandPalette.vue'\nimport NotificationsPopover from '@/components/blocks/NotificationsPopover.vue'\nimport { Button } from '@/components/ui/button'\nimport { Separator } from '@/components/ui/separator'\nimport {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from '@/components/ui/breadcrumb'\nimport { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'\nimport { ThemeSwitch } from '@/components/ui/theme-switch'\nimport { useTheme } from '@/composables/useTheme'\n\ninterface Crumb {\n  label: string\n  href?: string\n}\n\nwithDefaults(\n  defineProps<{\n    breadcrumbs?: Crumb[]\n    user?: { name: string; email: string; avatar?: string }\n  }>(),\n  {\n    breadcrumbs: () => [{ label: 'Dashboard' }],\n    user: () => ({ name: 'Alex Morgan', email: 'alex@example.com' }),\n  },\n)\n\nconst emit = defineEmits<{\n  (e: 'profile-select', key: string): void\n  (e: 'command-select', item: { label: string; hint?: string }): void\n}>()\n\nconst { theme, setTheme } = useTheme()\n</script>\n\n<template>\n  <SidebarProvider>\n    <Sidebar02 />\n    <SidebarInset>\n      <header\n        class=\"bg-background/80 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-30 flex h-14 w-full shrink-0 items-center justify-between border-b px-4 backdrop-blur-xl transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12\"\n      >\n        <div class=\"flex items-center gap-2\">\n          <SidebarTrigger class=\"-ml-1\" />\n          <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n          <Breadcrumb>\n            <BreadcrumbList>\n              <template v-for=\"(crumb, i) in breadcrumbs\" :key=\"i\">\n                <BreadcrumbItem :class=\"i === 0 ? 'hidden md:block' : ''\">\n                  <BreadcrumbLink\n                    v-if=\"crumb.href && i < breadcrumbs.length - 1\"\n                    :href=\"crumb.href\"\n                    class=\"text-muted-foreground/70 hover:text-foreground transition-colors\"\n                  >\n                    {{ crumb.label }}\n                  </BreadcrumbLink>\n                  <BreadcrumbPage v-else class=\"font-medium\">{{ crumb.label }}</BreadcrumbPage>\n                </BreadcrumbItem>\n                <BreadcrumbSeparator v-if=\"i < breadcrumbs.length - 1\" :class=\"i === 0 ? 'hidden md:block' : ''\" />\n              </template>\n            </BreadcrumbList>\n          </Breadcrumb>\n        </div>\n        <div class=\"flex items-center gap-1 px-2 sm:gap-3\">\n          <CommandPalette @select=\"(item) => emit('command-select', item)\" />\n          <div class=\"flex items-center gap-0.5\">\n            <ThemeSwitch :model-value=\"theme\" variant=\"icon-only\" @update:model-value=\"setTheme\" />\n            <NotificationsPopover>\n              <template #default=\"{ unreadCount }\">\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  class=\"text-muted-foreground hover:text-foreground relative size-8 rounded-lg\"\n                  aria-label=\"Notifications\"\n                >\n                  <Bell class=\"size-4\" />\n                  <span\n                    v-if=\"unreadCount > 0\"\n                    class=\"bg-primary ring-background absolute top-1.5 right-1.5 size-2 rounded-full ring-2\"\n                  />\n                </Button>\n              </template>\n            </NotificationsPopover>\n            <!-- ProfileMenu removed from header: the sidebar's NavUser\n                 (sidebar-02 footer) already owns the profile/account\n                 affordance. Two avatars in the same screen pulled the\n                 eye in conflicting directions. The block still accepts\n                 a `user` prop + emits `profile-select` so consumers can\n                 wire those into NavUser or a custom header slot. -->\n          </div>\n        </div>\n      </header>\n      <main class=\"flex flex-1 flex-col px-4 pt-4 pb-4 lg:px-6 lg:pt-6 lg:pb-6\">\n        <slot />\n      </main>\n    </SidebarInset>\n  </SidebarProvider>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/DashboardLayout.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/sidebar-02.json",
    "https://uipkge.dev/r/vue/command-palette.json",
    "https://uipkge.dev/r/vue/notifications-popover.json",
    "https://uipkge.dev/r/vue/theme-switch.json",
    "https://uipkge.dev/r/vue/use-theme.json",
    "https://uipkge.dev/r/vue/sidebar.json",
    "https://uipkge.dev/r/vue/breadcrumb.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/separator.json"
  ],
  "description": "Full dashboard shell — collapsible sidebar (sidebar-02) + sticky topbar (sidebar trigger, breadcrumb, command palette, theme switch, notifications, profile menu) + main content slot. Drop it in a Nuxt layout: `<DashboardLayout><slot /></DashboardLayout>`. Auto-pulls every transitive piece (sidebar-02, command-palette, notifications-popover, profile-menu, theme-switch).",
  "categories": [
    "dashboard",
    "layout"
  ]
}